﻿using System;
using System.ComponentModel;
using System.Linq.Expressions;

namespace Silverstone
{
    public abstract class ViewModelBase<TView, TViewModel> : INotifyPropertyChanged, IViewModel
        where TView : class, IView
        where TViewModel : class, IViewModel
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected TView View
        {
            private set;
            get;
        }

        void IViewModel.SetView(IView view)
        {
            TView strongView = view as TView;
            if (strongView == null)
            {
                throw new ArgumentException("View is invalid", "view");
            }
            this.View = strongView;
        }

        protected virtual void RaisePropertyChanged<T>(Expression<Func<TViewModel, T>> expr)
        {
            PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if (propertyChanged != null)
            {
                propertyChanged(this, new PropertyChangedEventArgs(((MemberExpression) expr.Body).Member.Name));
            }
        }

        protected abstract class CommandBase : Silverstone.CommandBase
        {
            protected TViewModel ViewModel { get; private set; }

            protected CommandBase(TViewModel viewModel)
            {
                this.ViewModel = viewModel;
            }
        }
    }
}